#pragma once
#include<condition_variable>
#include"server.hpp"

class LoopThread
{
private:
    /*实例化EventLoop对象，并且开始运作EventLoop模块的功能*/
    void ThreadEntry(){
        EventLoop loop;//这里定义一个对象出来而不是new一个出来，是想让他的生命周期跟着LoopThread这个类一起，要是LoopThread被释放了，他的生命周期就结束了
        {
            std::unique_lock<std::mutex> lock(_mutex);
            _loop=&loop;
            _cond.notify_all();
        }
        loop.Start();//正常情况下，是一直在循环运行的
    }
public:
    /*创建线程，设定线程入口函数*/
    LoopThread():_loop(NULL),_thread(std::thread(&LoopThread::ThreadEntry,this))
    {}
    /*返回当前线程关联的EventLoop对象指针*/
    EventLoop* GetLoop(){
        EventLoop* loop=NULL;
        {
            std::unique_lock<std::mutex> lock(_mutex);
            _cond.wait(lock,[&](){return _loop!=NULL;});//loop为NULL就一直阻塞
            loop=_loop;
        }
        return loop;
    }

private:
    EventLoop* _loop;//EventLoop指针变量，这个对象需要在线程内实例化
    std::thread _thread;//EventLoop对应的线程
    /*用于实现_loop获取的同步关系，避免线程创建了，但是_loop还没有实例化之前去获取_loop，此时就会获取到空的*/
    /*加入互斥锁和条件变量进行同步，保证线程安全保证顺序，就不会有这样的情况出现*/
    std::mutex _mutex;
    std::condition_variable _cond;
};



class LoopThreadPool
{
public:
    LoopThreadPool(EventLoop* baseloop):_thread_count(0),_next_idx(0),_baseloop(baseloop)
    {
    }
    void SetThreadCount(int count){_thread_count=count;}
    void Create(){
        if(_thread_count>0){
            _threads.resize(_thread_count);
            _loops.resize(_thread_count);
            for(int i=0;i<_thread_count;i++){
                _threads[i]=new LoopThread();//在这里没有创建完毕之前，在new出来之后，如果还没把EventLoop实例化完，那么他就不会返回，他就会去阻塞
                _loops[i]=_threads[i]->GetLoop();//在这里是会阻塞的
                //不需要担心，创建Thread之前，有连接过来，但是还办法分配的问题，因为只有建立好了才会给他分配
            }
        }
    }
    /*轮转分配*/
    EventLoop* NextLoop(){
        if(_thread_count==0)return _baseloop;
        _next_idx=(_next_idx+1)%_thread_count;
        return _loops[_next_idx];
    }


private:
    int _thread_count;
    int _next_idx;//索引
    EventLoop* _baseloop;
    std::vector<LoopThread*> _threads;
    std::vector<EventLoop*> _loops;
};